# -*-coding:utf-8-*-

from tornado.gen import coroutine, sleep
import tornado.ioloop
import tornado.web
import motor
import pymongo
import time
import pyrestful.rest
from pyrestful.rest import get
from tornado.options import define, options

define("port", default=18600, help="run on the given port", type=int)
define("rest", default=True, type=bool)
options.parse_command_line()

db_name = 'bora_v2_test'
coll_name = 'devices'
db = pymongo.MongoClient().get_database(db_name)
dao = db.get_collection(coll_name)
db_async = motor.MotorClient().get_database(db_name)
dao_async = db_async.get_collection(coll_name)


class AsyncTestHandler(tornado.web.RequestHandler):
    @coroutine
    def get(self, *args, **kwargs):
        if 2 == len(args):
            if 'ts' == args[0]:
                yield self.get_ts_async()
            elif 'db' == args[0]:
                yield self.get_db_async()
            elif 'sleep' == args[0]:
                yield self.get_ts_sleep_async()

    @coroutine
    def get_ts_async(self):
        result = {'ts_async': time.time()}
        self.finish(result)

    @coroutine
    def get_db_async(self):
        count = yield dao_async.count({'device_id': time.time()})
        self.finish({'count_async': count, 'ts': time.time()})

    @coroutine
    def get_ts_sleep_async(self):
        yield sleep(0.01)
        result = {'ts_sleep_async': time.time()}
        self.finish(result)


class TestHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        if 1 == len(kwargs):
            if 'ts' == kwargs['case']:
                self.get_ts()
            elif 'db' == kwargs['case']:
                self.get_db()
            elif 'sleep' == kwargs['case']:
                self.get_ts_sleep()

    def get_db(self):
        count = dao.count({'device_id': time.time()})
        self.finish({'count': count, 'ts': time.time()})

    def get_ts(self):
        result = {'ts': time.time()}
        self.finish(result)

    def get_ts_sleep(self):
        time.sleep(0.01)
        result = {'ts_sleep': time.time()}
        self.finish(result)


class PyRestfulHandler(pyrestful.rest.RestHandler):
    @get(_path='/api/sleep/async')
    @coroutine
    def get_ts_sleep_async(self):
        yield sleep(0.01)
        result = {'ts_sleep_async': time.time()}
        self.finish(result)

    @get(_path='/api/sleep')
    def get_ts_sleep(self):
        time.sleep(0.01)
        result = {'ts_sleep': time.time()}
        self.finish(result)

    @get(_path='/api/db')
    def get_db(self):
        count = dao.count({'device_id': time.time()})
        self.finish({'count': count, 'ts': time.time()})

    @get(_path='/api/db/async')
    @coroutine
    def get_db_async(self):
        count = yield dao_async.count({'device_id': time.time()})
        self.finish({'count_async': count, 'ts': time.time()})


def without_pyrestful():
    application = tornado.web.Application([
        (r'/api/(.*)/(.*)', AsyncTestHandler),
        (r'/api/(?P<case>.*)', TestHandler),
        (r'/api', TestHandler),
    ], debug=True)
    application.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()


def with_pyrestful():
    application = pyrestful.rest.RestService([PyRestfulHandler], debug=True)
    application.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()


if __name__ == '__main__':
    if options.rest:
        with_pyrestful()
    else:
        without_pyrestful()
